﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace YGWebMobileApi.Data
{
    /// <summary>
    /// Mobile API 管理器。通过反射获取标记有 MobileAPIAttribute 的类。通过接口 IProcessMessage 对其进行调用。
    /// </summary>
    public static class MobileAPIManager
    {
        private static Dictionary<string, MobileAPIDescription> MobileAPIs = new Dictionary<string, MobileAPIDescription>();

        /// <summary>
        /// 根据请求消息调用对应的 API
        /// </summary>
        /// <param name="reqMsg">请求消息</param>
        /// <returns></returns>
        public static MobileRspMsg CallAPI(MobileReqMsg reqMsg)
        {
            MobileAPIDescription dsp = null;

            lock (MobileAPIs)
            {
                if (MobileAPIs.Count <= 0)
                {
                    MobileAPIs = GetMobileAPIs();
                }

                if (MobileAPIs.ContainsKey(reqMsg.Head.APICode))
                {
                    dsp = MobileAPIs[reqMsg.Head.APICode];
                }
                else
                {
                    throw new Exception("服务端没能找到代码为 " + reqMsg.Head.APICode + " 的 API");
                }
            }

            if (dsp != null)
            {
                return dsp.CreateInstance().ProcessMessage(reqMsg);
            }
            else
            {
                throw new Exception("服务端没能找到代码为 " + reqMsg.Head.APICode + " 的 API");
            }
        }

        /// <summary>
        /// 获取所有 API 信息
        /// </summary>
        /// <returns></returns>
        public static MobileAPIDescription[] GetAPIDescriptions()
        {
            lock (MobileAPIs)
            {
                if (MobileAPIs.Count <= 0)
                {
                    MobileAPIs = GetMobileAPIs();
                }
                return MobileAPIs.Values.ToArray();
            }
        }

        /// <summary>
        /// 获取所有标记有 MobileAPIAttribute 的类
        /// </summary>
        /// <returns></returns>
        private static Dictionary<string, MobileAPIDescription> GetMobileAPIs()
        {
            var dict = new Dictionary<string, MobileAPIDescription>();
            Type[] types = typeof(MobileAPIManager).Assembly.GetTypes();
            foreach (var type in types)
            {
                object[] attribs = type.GetCustomAttributes(typeof(MobileAPIAttribute), false);
                if (attribs != null && attribs.Length > 0)
                {
                    var pm = type.GetInterface(typeof(IProcessMessage).FullName);
                    if (pm == null)
                    {
                        throw new Exception("类 " + type.FullName + " 必须实现接口 IProcessMessage");
                    }

                    MobileAPIAttribute attrib = (MobileAPIAttribute)attribs[0];
                    if (dict.ContainsKey(attrib.Code))
                    {
                        throw new Exception("APICode : " + attrib.Code + " 已被其它类使用请确认");
                    }
                    else
                    {
                        dict.Add(attrib.Code, new MobileAPIDescription(type, attrib.Code, attrib.Name));
                    }
                }
            }
            return dict;
        }
    }
}